package com.kaichaohulian.baocms.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.google.gson.Gson;
import com.kaichaohulian.baocms.R;
import com.kaichaohulian.baocms.adapter.ChooseCityAdapter;
import com.kaichaohulian.baocms.ecdemo.common.utils.LogUtil;
import com.kaichaohulian.baocms.entity.CityBean;
import com.kaichaohulian.baocms.entity.ShowCityBean;
import com.kaichaohulian.baocms.utils.PinyinUtils;
import com.kaichaohulian.baocms.view.ShowDialog;
import com.kaichaohulian.baocms.view_new.SideBar;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class ChooseCityActivity extends Activity {

    private static final String TAG = "ChooseCityActivity";

    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient = null;
    //声明定位回调监听器
    public AMapLocationListener mLocationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            tvLocation.setText(aMapLocation.getCity());
            LogUtil.d(TAG, aMapLocation.getAddress());
        }
    };
    //声明AMapLocationClientOption对象
    public AMapLocationClientOption mLocationOption = null;
    @BindView(R.id.img_return)
    ImageView imgReturn;
    @BindView(R.id.cancel)
    TextView cancel;
    @BindView(R.id.iv_icon)
    ImageView ivIcon;
    @BindView(R.id.v_line)
    View vLine;
    @BindView(R.id.et_search)
    EditText etSearch;
    @BindView(R.id.tv_tab1)
    TextView tvTab1;
    @BindView(R.id.tv_location)
    TextView tvLocation;
    @BindView(R.id.rv_citys)
    RecyclerView rvCitys;
    @BindView(R.id.sidebar)
    SideBar sidebar;
    @BindView(R.id.tv_letter)
    TextView tvLetter;

    private ReadCityTask readTask;
    private SortCityTask sortTask;
    private SearchCityTask searchCityTask;

    private ChooseCityAdapter adapter;

    private List<ShowCityBean> list = new ArrayList<>();
    private List<ShowCityBean> cacheSearchList = new ArrayList<>();
    private List<ShowCityBean> allList = new ArrayList<>();

    private LinearLayoutManager mLinearLayoutManager;
    private boolean move;
    private int mIndex;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_choose_city);
        ButterKnife.bind(this);
        initLocation();
        initViews();
        initDatas();

    }

    private void initViews() {
        adapter = new ChooseCityAdapter(this);

        mLinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        rvCitys.setLayoutManager(mLinearLayoutManager);
        rvCitys.setAdapter(adapter);

        rvCitys.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //在这里进行第二次滚动（最后的100米！）
                if (move) {
                    LogUtil.d(TAG, "--> if move");
                    move = false;
                    //获取要置顶的项在当前屏幕的位置，mIndex是记录的要置顶项在RecyclerView中的位置
                    int n = mIndex - mLinearLayoutManager.findFirstVisibleItemPosition();
                    if (0 <= n && n < rvCitys.getChildCount()) {
                        //获取要置顶的项顶部离RecyclerView顶部的距离
                        int top = rvCitys.getChildAt(n).getTop();
                        //最后的移动
                        rvCitys.scrollBy(0, top);
                    }
                }
            }

        });

        sidebar.setOnTouchingLetterChangedListener(new SideBar.OnTouchingLetterChangedListener() {
            @Override
            public void onTouchingLetterChanged(String s) {
                for (ShowCityBean bean : list) {
                    if (TextUtils.equals(String.valueOf(bean.getLetter()), s)) {
                        LogUtil.d(TAG, "--> onTouchingLetterChanged:letter = " + bean.getLetter());
                        int n = list.indexOf(bean);
                        mIndex = n;
                        moveToPosition(n);
                        break;
                    }
                }
            }
        });

        sidebar.setTextView(tvLetter);

        etSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                searchCityTask = new SearchCityTask();
                searchCityTask.execute(etSearch.getText().toString());
            }
        });
    }

    private void moveToPosition(int n) {
        //先从RecyclerView的LayoutManager中获取第一项和最后一项的Position
        int firstItem = mLinearLayoutManager.findFirstVisibleItemPosition();
        int lastItem = mLinearLayoutManager.findLastVisibleItemPosition();
        //然后区分情况
        if (n <= firstItem) {
            LogUtil.d(TAG, "--> n <= firstItem");
            //当要置顶的项在当前显示的第一个项的前面时
            rvCitys.scrollToPosition(n);
        } else if (n <= lastItem) {
            LogUtil.d(TAG, "--> n <= lastItem");
            //当要置顶的项已经在屏幕上显示时
            int top = rvCitys.getChildAt(n - firstItem).getTop();
            rvCitys.scrollBy(0, top);
        } else {
            LogUtil.d(TAG, "--> moveToPosition:else");
            //当要置顶的项在当前显示的最后一项的后面时
            rvCitys.scrollToPosition(n);
            //这里这个变量是用在RecyclerView滚动监听里面的
            move = true;
        }
    }

    private void initDatas() {

        ShowDialog.showDialog(this, "正在获取城市数据....", false, null);

        readTask = new ReadCityTask();
        readTask.execute("city.json");
        adapter.setOnItemClickListener(new ChooseCityAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
//                Toast.makeText(ChooseCityActivity.this, list.get(position).getCnName(), Toast.LENGTH_SHORT).show();
                Intent intent = new Intent();
                intent.putExtra("city", list.get(position).getCnName());
                setResult(1000, intent);
                finish();

            }
        });
    }

    private void initLocation() {
        //初始化定位
        mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
        mLocationClient.setLocationListener(mLocationListener);
//初始化AMapLocationClientOption对象
        mLocationOption = new AMapLocationClientOption();
        //设置定位模式为AMapLocationMode.Hight_Accuracy，高精度模式。
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //获取最近3s内精度最高的一次定位结果：
//设置setOnceLocationLatest(boolean b)接口为true，启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true，setOnceLocation(boolean b)接口也会被设置为true，反之不会，默认为false。
        mLocationOption.setOnceLocationLatest(true);
        //给定位客户端对象设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
//启动定位
        mLocationClient.startLocation();
    }

    @OnClick(R.id.img_return)
    public void onImgReturnClicked() {
        finish();
    }

    @OnClick(R.id.cancel)
    public void onCancelClicked() {
        finish();
    }

    private String getDataByAssets(String fileName) {
        try {
            StringBuffer json = new StringBuffer();
            InputStream inputStream = getAssets().open(fileName);
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String line = "";
            while ((line = bufferedReader.readLine()) != null) {
                json.append(line);
            }
            if (json.length() > 0) {
                return json.toString();
            } else {
                throw new NullPointerException("json is null");
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (NullPointerException e) {
            throw new RuntimeException(e);
        }
    }

    private class ReadCityTask extends AsyncTask<String, Void, List<CityBean>> {

        @Override
        protected List<CityBean> doInBackground(String... contexts) {
            String json = getDataByAssets(contexts[0]);
            Gson gson = new Gson();
            CityBean[] cityBeans = gson.fromJson(json, CityBean[].class);
            return Arrays.asList(cityBeans);
        }

        @Override
        protected void onPostExecute(List<CityBean> cityBeans) {
            super.onPostExecute(cityBeans);
            CityBean[] beans = cityBeans.toArray(new CityBean[cityBeans.size()]);
            sortTask = new SortCityTask();
            sortTask.execute(beans);
        }
    }

    private class SortCityTask extends AsyncTask<CityBean, Void, List<ShowCityBean>> {

        @Override
        protected List<ShowCityBean> doInBackground(CityBean... cityBeans) {
//            List<ShowCityBean> list = new ArrayList<>();
            for (int i = 'A'; i <= 'Z'; i++) {
                list.add(new ShowCityBean(ShowCityBean.TYPE_LETTER, (char) i, String.valueOf((char) i), String.valueOf((char) i)));
            }
            for (CityBean bean : cityBeans) {
                List<CityBean.CitiesBean> cities = bean.getCities();
                for (CityBean.CitiesBean citiesBean : cities) {
                    String areaName = citiesBean.getAreaName();
                    char alpha = PinyinUtils.getAlpha(areaName);
                    list.add(new ShowCityBean(ShowCityBean.TYPE_CITY, alpha, areaName, citiesBean.getAreaId()));
                }
            }

            Map<Character, Integer> map = new HashMap<>();

            for (ShowCityBean bean : list) {
                char letter = bean.getLetter();
                if (map.get(letter) == null) {
                    map.put(letter, 1);
                } else {
                    map.put(letter, map.get(letter) + 1);
                }
            }

            List<Character> removeLetterList = new ArrayList<>();

            Set<Map.Entry<Character, Integer>> entries = map.entrySet();

            for (Map.Entry<Character, Integer> entry : entries) {
                if (entry.getValue() <= 1) {
                    removeLetterList.add(entry.getKey());
                }
            }

            List<ShowCityBean> removeList = new ArrayList<>();
            for (ShowCityBean bean : list) {
                char letter = bean.getLetter();
                for (Character character : removeLetterList) {
                    if (letter == character) {
                        removeList.add(bean);
                    }
                }
            }

            list.removeAll(removeList);
            allList.clear();

            Collections.sort(list);
            allList.addAll(list);

            return list;
        }

        @Override
        protected void onPostExecute(List<ShowCityBean> list) {
            super.onPostExecute(list);

            adapter.refreshDatas(list);
            ShowDialog.dissmiss();
        }
    }

    private class SearchCityTask extends AsyncTask<String, Void, List<ShowCityBean>> {

        @Override
        protected List<ShowCityBean> doInBackground(String... strings) {
            String keyword = strings[0];

            if (TextUtils.isEmpty(keyword)) {
                list.clear();
                list.addAll(allList);
            } else {
                cacheSearchList.clear();
                for (ShowCityBean bean : allList) {
                    if (bean.getCnName().contains(keyword)) {
                        cacheSearchList.add(bean);
                    }
                }

                list.clear();
                list.addAll(cacheSearchList);
            }

            return list;
        }

        @Override
        protected void onPostExecute(List<ShowCityBean> list) {
            super.onPostExecute(list);
            adapter.refreshDatas(list);
        }
    }
}
